package com.mspbots.api.client;

import com.mspbots.api.utils.ClientUrlParamsUtils;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.util.Map;

/**
 * com.mspbots.api.client.A
 *
 * @author Alex bob(https://github.com/vnobo)
 * @date Created by 2019/11/12
 */
public abstract class AbstractClient implements BaseClient {

    protected WebClient webClient;

    protected AbstractClient(WebClient webClient) {
        this.webClient = webClient;
    }

    @Override
    public <T> Mono<T> post(String path, Object body, Class<T> responseType) {
        return this.webClient.post()
                .uri(path)
                .accept(MediaType.APPLICATION_JSON)
                .bodyValue(body)
                .retrieve()
                .bodyToMono(responseType);
    }

    @Override
    public <T> Flux<T> postFlux(String path, Object body, Class<T> responseType) {
        return this.webClient.post()
                .uri(path)
                .accept(MediaType.APPLICATION_JSON)
                .bodyValue(body)
                .retrieve()
                .bodyToFlux(responseType);
    }


    @Override
    public <T> Mono<T> get(String path, Map<String, Object> params, Class<T> responseType) {
        return this.webClient.get()
                .uri(uriBuilder -> uriBuilder.path(path)
                        .queryParams(ClientUrlParamsUtils.form(params)).build())
                .accept(MediaType.APPLICATION_JSON)
                .retrieve()
                .bodyToMono(responseType);
    }

    @Override
    public <T> Flux<T> getFlux(String path, Map<String, Object> params, Class<T> responseType) {
        return this.webClient.get()
                .uri(uriBuilder -> uriBuilder.path(path).queryParams(ClientUrlParamsUtils.form(params)).build())
                .accept(MediaType.APPLICATION_JSON)
                .retrieve()
                .bodyToFlux(responseType);
    }

    @Override
    public <T> Mono<T> put(String path, Object body, Class<T> responseType) {
        return this.webClient.put()
                .uri(uriBuilder -> uriBuilder.path(path).build())
                .bodyValue(body)
                .retrieve()
                .bodyToMono(responseType);
    }

    @Override
    public <T> Mono<T> delete(String path, Map<String, Object> params, Class<T> responseType) {
        return this.webClient.delete()
                .uri(uriBuilder -> uriBuilder.path(path)
                        .queryParams(ClientUrlParamsUtils.form(params))
                        .build())
                .retrieve()
                .bodyToMono(responseType);
    }

}
